from flask import Flask, abort, request, jsonify
import redis
import json
import time
import datetime
import logging
#from gevent.wsgi import WSGIServer
from gevent.pywsgi import WSGIServer

# GetTime
ServiceInitTime = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
# 创建redis全局变量
RedisHost='10.4.1.106'
RedisPort = '6383'
RedisStatusDB = '0'
RedisTrackDB = '2'
# password='xz85742629'

RedisConnection = redis.Redis(host=RedisHost,port=RedisPort, db=RedisStatusDB)
RedisTrackConnection = redis.Redis(host=RedisHost,port=RedisPort, db=RedisTrackDB)

ServiceInitTime = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))

app = Flask(__name__)


def Log(name,value=";",level="debug"):
    name = str(name)
    value = str(value)
    level = str(level)
    if level=="debug":
        #print(name+"|"+value)
        return None
    elif level=="info":
        print(name+"|"+value)
    elif level == "warning":
        print(name+"|"+value)
    elif level == "error":
        print(name+"|"+value)
    elif level == "critical":
        print(name+"|"+value)
    else :
        print("Log else")

    LogPath = "./IOVServiceWSGI" + ServiceInitTime + ".log"
    LogFile = open(LogPath, 'a')
    LogTime = str(time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())))
    LogFile.write(LogTime+"|"+name+"|"+value+"|"+level+'\n')
    LogFile.close()
    return None

def timestamp_datetime(value):
    format = '%Y-%m-%d %H:%M:%S'
    # value为传入的值为时间戳(整形)，如：1332888820
    value = time.localtime(int(value))
    ## 经过localtime转换后变成
    ## time.struct_time(tm_year=2012, tm_mon=3, tm_mday=28, tm_hour=6, tm_min=53, tm_sec=40, tm_wday=2, tm_yday=88, tm_isdst=0)
    # 最后再经过strftime函数转换为正常日期格式。
    dt = time.strftime(format, value)
    return dt

def datetime_timestamp(dt):
    try:
        #print("dt|"+dt)
        # dt为字符串
        # 中间过程，一般都需要将字符串转化为时间数组
        time.strptime(dt, '%Y-%m-%d %H:%M:%S')
        ## time.struct_time(tm_year=2012, tm_mon=3, tm_mday=28, tm_hour=6, tm_min=53, tm_sec=40, tm_wday=2, tm_yday=88, tm_isdst=-1)
        # 将"2012-03-28 06:53:40"转化为时间戳
        s = time.mktime(time.strptime(dt, '%Y-%m-%d %H:%M:%S'))
        #print(int(s))
        return int(s)
    except:
        Log("except:" )
        #print("dt:"+dt)
        dayBefore = dt[0:8]
        #print("dayBefore|" + dayBefore)
        dayMark = dt[8:10]
        #print("dayMark|" + dayMark)
        dayAfter = dt[10:19]
        #print("dayAfter|" + dayAfter)
        preDay = str(int(dayMark)-1)
        #print("preDay|"+preDay)
        if len(preDay) == 1:
            preDay = "0" + preDay
        DTpreDay = str(dayBefore)+str(preDay)+str(dayAfter)
        #print("DTpreDay|"+DTpreDay)
        # dt为字符串
        # 中间过程，一般都需要将字符串转化为时间数组
        time.strptime(DTpreDay, '%Y-%m-%d %H:%M:%S')
        ## time.struct_time(tm_year=2012, tm_mon=3, tm_mday=28, tm_hour=6, tm_min=53, tm_sec=40, tm_wday=2, tm_yday=88, tm_isdst=-1)
        # 将"2012-03-28 06:53:40"转化为时间戳
        exceptS = time.mktime(time.strptime(DTpreDay, '%Y-%m-%d %H:%M:%S'))
        return int(exceptS)

#-----------------------------------------------------------------------------------------
def getStatusData(terminalCodeList):
    Log("getStatusData", "START")
    Log("terminalCodeList", terminalCodeList)
    ResultDict = []
    ListLen = len(terminalCodeList)
    Log("getStatusData.ListLen", ListLen);
    for index in range(ListLen):
        Log("[index]:" , index);
        Log("terminalCodeList[index]:", terminalCodeList[index]);
        VINResult = getVINStatusData(terminalCodeList[index])
        Log("len(VINResult):", len(VINResult));
        if len(VINResult)>0:
            ResultDict.append(VINResult)

    # Sorting from BIG to SMALL
    for ListIndexA in range(len(ResultDict)):
        for ListIndexB in range(ListIndexA,len(ResultDict)):
            if ResultDict[ListIndexA]['lastRefreshTime']<ResultDict[ListIndexB]['lastRefreshTime']:
                vinResultTemp = ResultDict[ListIndexA]
                ResultDict[ListIndexA] = ResultDict[ListIndexB]
                ResultDict[ListIndexB] = vinResultTemp
    ResultDictVIN = []
    ResultDictDistinct = []
    for ResultIndex in range(len(ResultDict)):
        if ResultDict[ResultIndex]['terminalCode'] not in ResultDictVIN:
            ResultDictVIN.append(ResultDict[ResultIndex]['terminalCode'])
            ResultDictDistinct.append(ResultDict[ResultIndex])
    return ResultDictDistinct

def getVINStatusData(terminalCode):
    Log("getVINStatusData", "START");
    HashGetName = "tm30_status_ehs3_VIN_pcol_realtime"
    StatusName = "tm30_status_ehs3_vin_value_cache"
    RedisStatusStoreName = "EVStatusStore"
    #HashGetKey = "LFPHC7PE1K1A06216"
    #HashGetKey = terminalCodeList[0]
    #Log(HashGetName, HashGetKey);
    #print(RedisConnection.hget("tm30_status_ehs3_VIN_pcol_realtime", "LFPHC7PE6K1A13713"))
    # print(RedisConnection.hget(HashGetName, HashGetKey))
    #global StatusName
    Log("getVINStatusData.RedisStatusStoreName", RedisStatusStoreName);
    redisResult = RedisTrackConnection.hget(RedisStatusStoreName, terminalCode)

    if redisResult == None:
        Log('redisResult', 'is None');
    else:
        Log('redisResult', 'is OK');
        Log("redisResult", redisResult);
        redisResultDecode = redisResult.decode('utf-8')
        redisResultClean = redisResultDecode.replace(' u\'', ' \'')
        redisResultClean = redisResultClean.replace('{u\'', '{\'')
        redisResultClean = redisResultClean.replace('\'', '\"')
        Log("redisResultClean", redisResultClean);

        # redisResultDecodeLoads = json.loads(redisResultDecode)

        # print(redisResultDecodeLoads);
        Log("type(redisResultClean)",type(redisResultClean))
        global redisResultJSON
        redisResultJSON = json.loads(redisResultClean)
    # redisResultJSON = json.dumps(redisResultClean)
    #print(type(redisResultJSON))
    # print(type(jsObj))
    Log("redisResultJSON", redisResultJSON);


    eventCode = redisResultJSON['event_code']
    Log("eventCode", eventCode);
    terminalCode = redisResultJSON['vin']
    Log("terminalCode", terminalCode);
    lat = redisResultJSON['data']['GPS003']['val']  # GPS003	纬度
    Log("lat", lat);
    lgt = redisResultJSON['data']['GPS002']['val']  # GPS002	经度
    Log("lgt", lgt);
    angle = redisResultJSON['data']['GPS006']['val']  # GPS006	方向
    Log("angle", angle);
    speed = redisResultJSON['data']['V019']['val']  # V019	整车车速
    Log("speed", speed);
    totalKm = redisResultJSON['data']['V015']['val']  # V015	总里程
    Log("totalKm", totalKm);
    enableKm = redisResultJSON['data']['V133']['val']  # V133	续航剩余里程
    Log("enableKm", enableKm);
    lastRefreshTime = redisResultJSON['data']['GPS007']['val']  # GPS007	GPS时间
    Log("lastRefreshTime", lastRefreshTime);
    soc = redisResultJSON['data']['E010']['val']  # E010	电池电量（SOC）
    Log("soc", soc);
    dt = timestamp_datetime(lastRefreshTime[0:10])
    Log("dt", dt);

    ResultVINDict = {}
    ResultVINDict['eventCode'] = eventCode
    ResultVINDict['terminalCode'] = terminalCode
    ResultVINDict['lat'] = lat
    ResultVINDict['lgt'] = lgt
    ResultVINDict['angle'] = angle
    ResultVINDict['speed'] = speed
    ResultVINDict['totalKm'] = totalKm
    ResultVINDict['enableKm'] = enableKm
    ResultVINDict['lastRefreshTime'] = lastRefreshTime
    ResultVINDict['soc'] = soc
    ResultVINDict['dt'] = dt

    return ResultVINDict

@app.route('/redis/queryVehicleInfoByTerminalCode', methods=['POST'])
# in parameter ：{"terminalCode":"LFPHC7PE0K1A06501"}
def queryVehicleInfoByTerminalCode():
    time_queryVehicleInfoByTerminalCode_start=time.time()
    Log('time_queryVehicleInfoByTerminalCode_start',time_queryVehicleInfoByTerminalCode_start)

    Log("queryVehicleInfoByTerminalCode");
    if not request.json or 'terminalCode' not in request.json:
        abort(400)

    terminalCode = request.json['terminalCode']
    Log("terminalCode", terminalCode);
    terminalCodeList = terminalCode.split(",")
    Log("terminalCodeList",terminalCodeList);
    ResultDict = getStatusData(terminalCodeList)
    #tasks.append(task)

    time_queryVehicleInfoByTerminalCode_end = time.time()
    Log('queryVehicleInfoByTerminalCode time cost', time_queryVehicleInfoByTerminalCode_end - time_queryVehicleInfoByTerminalCode_start)
    return jsonify({'code': '200','message': '成功','object': ResultDict})
    #return "queryVehicleInfoByTerminalCode!"


#-----------------------------------------------------------------------------------------
def getTrackResult(vin,startTime,endTime):
    Log("getTrackResult", "START");
    trackName = vin

    Log("getTrackResult.trackName", trackName);

    #startTimeTrip = startTime.lstrip('(').rstrip(')')
    #startTimeTripDate = datetime.datetime.strptime(startTimeTrip, "%Y-%m-%d %H:%M:%S")
    #startTimeUnixStamp = time.mktime(startTimeTripDate.timetuple())
    startTimeUnixStamp = datetime_timestamp(startTime)
    Log("startTimeUnixStamp",startTimeUnixStamp)
    #endTimeTrip = endTime.lstrip('(').rstrip(')')
    #endTimeTripDate = datetime.datetime.strptime(endTimeTrip, "%Y-%m-%d %H:%M:%S")
    #endTimeUnixStamp = time.mktime(endTimeTripDate.timetuple())
    endTimeUnixStamp = datetime_timestamp(endTime)
    Log("endTimeUnixStamp", endTimeUnixStamp)
    Log(type(endTimeUnixStamp))
    startTimeUnixStampString = str(startTimeUnixStamp).split(".")[0]+"000000000"
    Log("startTimeUnixStampString",startTimeUnixStampString)
    Log("startTimeUnixStampString.len", len(startTimeUnixStampString))
    endTimeUnixStampString = str(endTimeUnixStamp).split(".")[0]+"000000000"
    Log("endTimeUnixStampString",endTimeUnixStampString)
    Log("endTimeUnixStampString.len", len(endTimeUnixStampString))
    startTimeRedisKey = startTimeUnixStampString+"0000000000000000000"
    Log("startTimeRedisKey",startTimeRedisKey)
    Log("startTimeRedisKey.len", len(startTimeRedisKey))

    endTimeRedisKey = endTimeUnixStampString+"0000000000000000000"
    Log("endTimeRedisKey",endTimeRedisKey)
    Log("endTimeRedisKey.len", len(endTimeRedisKey))

    TrackResult = RedisTrackConnection.hkeys(vin)
    Log(TrackResult)
    Log("type(TrackResult)",type(TrackResult))
    Log("len(TrackResult)",len(TrackResult))
    TrackResultLength = len(TrackResult)
    #TrackResultDecode= TrackResult.
    Log("type(TrackResult[0])",type(TrackResult[0]))

    TrackResultDict = []
    for index in range(TrackResultLength):
        TrackResultString = TrackResult[index].decode()
        Log("TrackResultString",TrackResultString)
        Log("type(TrackResultString)",type(TrackResultString))

        #leftTime = TrackResultString[0:18]
        #rightTime = TrackResultString[19:37]
        # print("leftTime",leftTime)
        #Log("len(leftTime)",len(leftTime))
        #print("rightTime", rightTime)
        #Log("len(rightTime)", len(rightTime))

        if startTimeRedisKey<TrackResultString and TrackResultString<endTimeRedisKey:
            redisTrackResult = RedisTrackConnection.hget(vin, TrackResultString)
            redisTrackResultDecode = redisTrackResult.decode('utf-8')
            redisTrackResultClean = redisTrackResultDecode.replace(' u\'', ' \'')
            redisTrackResultClean = redisTrackResultClean.replace('{u\'', '{\'')
            redisTrackResultClean = redisTrackResultClean.replace('\'', '\"')
            TrackResultVINDict = {}
            Log("redisTrackResultClean",redisTrackResultClean)
            try:
                redisTrackResultJSON = json.loads(redisTrackResultClean)
                eventCode = redisTrackResultJSON['event_code']
                Log("eventCode", eventCode);
                terminalCode = redisTrackResultJSON['vin']
                Log("terminalCode", terminalCode);
                lat = redisTrackResultJSON['data']['GPS003']['val']  # GPS003	纬度
                Log("lat", lat);
                lgt = redisTrackResultJSON['data']['GPS002']['val']  # GPS002	经度
                Log("lgt", lgt);
                angle = redisTrackResultJSON['data']['GPS006']['val']  # GPS006	方向
                Log("angle", angle);
                speed = redisTrackResultJSON['data']['V019']['val']  # V019	整车车速
                Log("speed", speed);
                totalKm = redisTrackResultJSON['data']['V015']['val']  # V015	总里程
                Log("totalKm", totalKm);
                enableKm = redisTrackResultJSON['data']['V133']['val']  # V133	续航剩余里程
                Log("enableKm", enableKm);
                lastRefreshTime = redisTrackResultJSON['data']['GPS007']['val']  # GPS007	GPS时间
                Log("lastRefreshTime", lastRefreshTime);
                soc = redisTrackResultJSON['data']['E010']['val']  # E010	电池电量（SOC）
                Log("soc", soc);
                dt = timestamp_datetime(lastRefreshTime[0:10])
                #Log("lastRefreshTime", lastRefreshTime)
                #Log("lastRefreshTime[0:10]", lastRefreshTime[0:10])
                Log("dt", dt);

                TrackResultVINDict['eventCode'] = eventCode
                TrackResultVINDict['terminalCode'] = terminalCode
                TrackResultVINDict['lat'] = lat
                TrackResultVINDict['lgt'] = lgt
                TrackResultVINDict['angle'] = angle
                TrackResultVINDict['speed'] = speed
                TrackResultVINDict['totalKm'] = totalKm
                TrackResultVINDict['enableKm'] = enableKm
                TrackResultVINDict['lastRefreshTime'] = lastRefreshTime
                TrackResultVINDict['soc'] = soc
                TrackResultVINDict['dt'] = dt
            except:
                Log("getTrackResult","except")
                continue

            finally:
                Log("getTrackResult","finally")

            TrackResultDict.append(TrackResultVINDict)

    # Sorting from SMALL to BIG
    for ListIndexA in range(len(TrackResultDict)):
        for ListIndexB in range(ListIndexA,len(TrackResultDict)):
            if TrackResultDict[ListIndexA]['lastRefreshTime']>TrackResultDict[ListIndexB]['lastRefreshTime']:
                vinResultTemp = TrackResultDict[ListIndexA]
                TrackResultDict[ListIndexA] = TrackResultDict[ListIndexB]
                TrackResultDict[ListIndexB] = vinResultTemp

    return TrackResultDict;


@app.route('/redis/queryVehicleTrackInfoByTerminalCode', methods=['POST'])
# in parameter ：{"terminalCode":"LFPHC7PEXK1A07400","startTime":"2018-01-29 00:00:00","endTime":"2020-01-29 23:59:59"}
def queryVehicleTrackInfoByTerminalCode():
    time_queryVehicleTrackInfoByTerminalCode_start=time.time()
    Log('time_queryVehicleTrackInfoByTerminalCode_start', time_queryVehicleTrackInfoByTerminalCode_start, "info")
    if not request.json or 'terminalCode' not in request.json or 'startTime' not in request.json or 'endTime' not in request.json:
        abort(400)

    terminalCode = request.json['terminalCode']
    Log("terminalCode", terminalCode);
    startTime = request.json['startTime']
    Log("startTime", startTime);
    endTime = request.json['endTime']
    Log("endTime", endTime);

    ResultDict = {}
    TrackResultDict = getTrackResult(terminalCode,startTime,endTime)
    time_queryVehicleTrackInfoByTerminalCode_end = time.time()
    Log('queryVehicleTrackInfoByTerminalCode time cost', time_queryVehicleTrackInfoByTerminalCode_end - time_queryVehicleTrackInfoByTerminalCode_start,"info")
    return jsonify({'code': '200','message': '成功','object': TrackResultDict})


if __name__=="__main__":
    #app.run(host='0.0.0.0', port=8091, debug=True)
    WSGIServer(('0.0.0.0', 8091), app).serve_forever() # 8091是生产环境，6379-6390可用，
